let init_display width height =
  begin
    GlDraw.shade_model `smooth;
    GlClear.color (1.0, 0.0, 0.0);
    GlClear.depth 1.0;
    GlClear.clear [`color; `depth];
    Gl.enable `depth_test;
    GlFunc.depth_func `lequal;
    GlMisc.hint `perspective_correction `nicest;
  end

let rtri = ref 0.0
let rquad = ref 0.0

let display_triangle (a,c1,b,c2,c,c3) =
  begin
    GlDraw.color c1;
    GlDraw.vertex3 a;
    GlDraw.color c2;
    GlDraw.vertex3 b;
    GlDraw.color c3;
    GlDraw.vertex3 c;
  end
    
let rot = ref 0.0
let rot_x = ref 0.0
let rot_y = ref 0.0
let rot_z = ref 0.0
let trans_x = ref (-0.5)
let trans_y = ref (-0.05)
let trans_z = ref (-0.5)
let zoom = ref 1.0

let display_map () =
  GlMat.load_identity ();
  GlMat.mode `projection;
  GlMat.scale3 (!zoom,!zoom,!zoom);
  GlMat.rotate3 !rot_x (1.0,0.0,0.0);
  GlMat.rotate3 !rot_y (0.0,1.0,0.0);
  GlMat.translate3 (!trans_x, !trans_y, !trans_z);
  GlDraw.begins `triangles;
  for i = 0 to (Array.length (!ObjReader.face) - 1) do
    try
      let (x,y,z) = Array.get !ObjReader.face i in
      let (x1,y1,z1) = Array.get !ObjReader.vertex (x-1) in
      let (x2,y2,z2) = Array.get !ObjReader.vertex (y-1) in
      let (x3,y3,z3) = Array.get !ObjReader.vertex (z-1) in
      let c1 = ColorList.get_color (int_of_float y1) in
      let c2 = ColorList.get_color (int_of_float y2) in
      let c3 = ColorList.get_color (int_of_float y3) in
      display_triangle
	((x1/.100.,y1/.100.,z1/.100.), c1,
	 (x2/.100.,y2/.100.,z2/.100.), c2,
	 (x3/.100.,y3/.100.,z3/.100.), c3);
    with
	Invalid_argument "index out of bounds" ->
	  print_string "display_map"
  done;
  GlDraw.ends ()
    
let display () =
  begin
    GlClear.clear [`color; `depth];
    display_map ();
    Gl.flush ();
    Glut.swapBuffers ();
  end  

let reshape ~w ~h =
  begin
    let ratio = (float_of_int w)/.(float_of_int h) in
    GlDraw.viewport 0 0 w h;
    GlMat.mode `projection;
    GlMat.load_identity ();
    GluMat.perspective 45.0 ratio (1.0, 10000.0);
    GlMat.mode `projection;
    GlMat.load_identity ();
  end

let keyboard ~key ~x ~y =
  match key with
    | 27 (* ESC *)-> Glut.destroyWindow (Glut.getWindow ());
    | _ -> ()

let camera ~key ~x ~y =
  match key with
    | Glut.KEY_LEFT -> rot_y := !rot_y +. 1.0;
    | Glut.KEY_RIGHT -> rot_y := !rot_y -. 1.0;
    | Glut.KEY_UP -> rot_x := !rot_x +. 1.0;
    | Glut.KEY_DOWN -> rot_x := !rot_x -. 1.0;
    | Glut.KEY_F1 -> zoom := !zoom +. 0.04
    | Glut.KEY_F2 -> 
      if not(!zoom -. 0.04 <= 0.) then
	zoom := !zoom -. 0.04
    | Glut.KEY_F3 -> trans_x := !trans_x -. 0.01;
    | Glut.KEY_F4 -> trans_x := !trans_x +. 0.01;
    | Glut.KEY_F5 -> trans_y := !trans_y -. 0.01;
    | Glut.KEY_F6 -> trans_y := !trans_y +. 0.01;  
    | _ -> ()

let idle () =
  display ()

let init_window (width,height) =
  begin
    ignore(Glut.init Sys.argv);
    Glut.initDisplayMode ~depth:true ~double_buffer:true ();
    Glut.initWindowSize ~w:width ~h:height;
    ignore(Glut.createWindow ~title:"Ramani Ya Mradi : Vue 3D");
    Glut.displayFunc display;
    Glut.reshapeFunc reshape;
    Glut.keyboardFunc keyboard;
    Glut.specialFunc camera;
    Glut.idleFunc (Some idle);
    Glut.mainLoop();
  end

let init_3d () =
  begin
    let (width,height) = (800,600) in
    ObjReader.init_tab "map.obj";
    init_window (width,height);
  end

(*let i_displayw width height =
  begin
    GlDraw.shade_model `smooth;
    GlClear.color (0.0, 0.0, 0.0);
    GlClear.depth 1.0;
    GlClear.clear [`color; `depth];
    Gl.enable `depth_test;
    GlFunc.depth_func `lequal;
    GlMisc.hint `perspective_correction `nicest;
  end  

let displayw area () =
  begin
    GlClear.clear [`color; `depth];
    display_map ();
    Gl.flush ();
    area#swapBuffers ();
  end
  

let displayw area width height =
  begin
    GMain.Timeout.add ~ms:170 
      ~callback:(
	begin 
	  fun () ->
	    displayw area ();
	    true
	end);
    
    area#connect#display ~callback:(fun () -> ());
    area#connect#reshape ~callback:(reshape);
    area#connect#realize ~callback:(
      fun () ->
	begin
	  i_displayw 700 500;
	  reshape width height;
	end);
  end*)
